﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using ScheduleMaker.DB;
using ScheduleMaker.DB.CoreDAO;
using ScheduleMaker.DB.Domain;
using ScheduleMaker.DB.Domain.Core;
using ScheduleMaker.ConfigManager;
using ScheduleMaker.ScheduleManager;

namespace ScheduleMaker
{
    public partial class smScheduleForm : Form
    {

        const int MAX_NUMBER_OF_SUBJECTS = 50;

        const int columnMinimumWidth = 190;

        IList<DB.Domain.Core.Day> days;
        IList<Group> groups;
        IList<Category> categories;
        IList<Classroom> classrooms;
        IList<Teacher> teachers;
        IList<ClassHour> classHours;

        Color[] colors;

        Mode mode;

        public smScheduleForm()
        {
            InitializeComponent();

            if (ConfigManager.ConfigManager.isConfigLoaded())
            {
                mode = ConfigManager.ConfigManager.getConfiguration().Type;
            }

            if (mode == Mode.School)
            {
                this.Text = "ScheduleMaker - Przeglądanie Planu - TRYB: SZKOŁA";
            }
            else
            {
                this.labelGroup.Text = "Blok:";
                this.Text = "ScheduleMaker - Przeglądanie Planu - TRYB: UCZELNIA";
            }

            grid.Rows.Clear();
            grid.DefaultCellStyle.WrapMode = DataGridViewTriState.True;
            grid.DefaultCellStyle.Alignment = DataGridViewContentAlignment.MiddleCenter;

            loadDays();
            loadClassHours();
            loadGroupsOrCategories();
            loadTeachers();
            loadClassrooms();

            colors = new Color[] {
                Color.DarkOrange ,
                Color.Yellow ,
                Color.DeepSkyBlue ,
                Color.Violet ,
                Color.LightGreen ,
                Color.Chocolate ,
                Color.DarkGray ,
                Color.LimeGreen ,
                Color.MediumAquamarine ,
                Color.DarkTurquoise ,
                Color.Goldenrod ,
                Color.LightBlue ,
                Color.MediumOrchid ,
                Color.Gold ,
                Color.Tomato ,
                Color.HotPink ,
                Color.Orange ,
                Color.GreenYellow ,
                Color.Magenta ,
                Color.Orchid ,
                Color.RosyBrown ,
                Color.Chartreuse ,
            };

            autoResize();

        }


        private void loadDays()
        {
            // Wczytanie dni tygodnia.
            DayDAO dayDAO = DAOFactory.getDayDAO(mode);
            days = dayDAO.getAll();

            DateTime today = DateTime.Now;
            DateTime lastMonday = today;
            while (lastMonday.DayOfWeek.ToString() != "Monday")
            {
                lastMonday = lastMonday.AddDays(-1);
            }
            DateTime currentDate = lastMonday;
            
            grid.ColumnCount = days.Count;
            int i = 0;
            foreach (var day in days)
            {
                grid.Columns[i].Name = day.Name + "\n" + currentDate.ToShortDateString();
                grid.Columns[i].MinimumWidth = columnMinimumWidth;
                i++;
                currentDate = currentDate.AddDays(1);
            }
        }


        private void loadClassHours()
        {
            grid.RowHeadersWidth = 200;

            ClassHourDAO classHourDAO = DAOFactory.getClassHourDAO(mode);
            classHours = classHourDAO.getAll();

            int i = 0;
            foreach (var classHour in classHours)
            {
                string[] rowValues = { };
                grid.Rows.Add(rowValues);
                grid.Rows[i++].HeaderCell.Value =
                    classHour.Begin.ToString().Substring(0, 5) +
                    " - " +
                    classHour.End.ToString().Substring(0, 5)
                ;
            }
        }


        private void loadGroupsOrCategories()
        {
            if (mode == Mode.School)
            {
                GroupDAO groupDAO = DAOFactory.getGroupDAO(mode);
                groups = groupDAO.getAll();
                foreach (var elem in groups)
                {
                    comboBoxGroups.Items.Add(elem.Id + " - " + elem.Name);
                }
                comboBoxGroups.DropDownStyle = ComboBoxStyle.DropDownList;
            }
            else
            {
                CategoryDAO categoryDAO = DAOFactory.getCategoryDAO(mode);
                categories = categoryDAO.getAll();
                foreach (var category in categories)
                {
                    comboBoxGroups.Items.Add(category.Id + " - " + category.Name);
                }
                comboBoxGroups.DropDownStyle = ComboBoxStyle.DropDownList;
            }
        }


        private void loadClassrooms()
        {
            ClassroomDAO classroomDAO = DAOFactory.getClassroomDAO(mode);
            classrooms = classroomDAO.getAll();
            foreach (var elem in classrooms)
            {
                comboBoxClassrooms.Items.Add(elem.Id + " - " + elem.Name);
            }
            comboBoxClassrooms.DropDownStyle = ComboBoxStyle.DropDownList;
        }


        private void loadTeachers()
        {
            TeacherDAO teacherDAO = DAOFactory.getTeacherDAO(mode);
            teachers = teacherDAO.getAll();
            foreach (var elem in teachers)
            {
                comboBoxTeachers.Items.Add(elem.Id + " - " + elem.Name);
            }
            comboBoxTeachers.DropDownStyle = ComboBoxStyle.DropDownList;
        }


        private void comboBoxGroups_SelectedIndexChanged_1(object sender, EventArgs e)
        {
            if (comboBoxGroups.SelectedIndex != -1)
            {
                comboBoxClassrooms.SelectedIndex = -1;
                comboBoxTeachers.SelectedIndex = -1;
            }
        }

        private void comboBoxClassrooms_SelectedIndexChanged_1(object sender, EventArgs e)
        {
            if (comboBoxClassrooms.SelectedIndex != -1)
            {
                comboBoxGroups.SelectedIndex = -1;
                comboBoxTeachers.SelectedIndex = -1;
            }
        }

        private void comboBoxTeachers_SelectedIndexChanged_1(object sender, EventArgs e)
        {
            if (comboBoxTeachers.SelectedIndex != -1)
            {
                comboBoxGroups.SelectedIndex = -1;
                comboBoxClassrooms.SelectedIndex = -1;
            }
        }


        private void buttonShowPlan_Click_1(object sender, EventArgs e)
        {
            Cursor = Cursors.WaitCursor;

            int selectedIndex;
            if ((selectedIndex = comboBoxGroups.SelectedIndex) != -1)
            {
                if (mode == Mode.School)
                {
                    Group group = groups.ElementAt(selectedIndex);
                    loadGroupPlan(group);
                }
                else
                {
                    Category category = categories.ElementAt(selectedIndex);
                    loadCategoryPlan(category);
                }
            }
            else if ((selectedIndex = comboBoxClassrooms.SelectedIndex) != -1)
            {
                Classroom classroom = classrooms.ElementAt(selectedIndex);
                loadClassroomPlan(classroom);
            }
            else if ((selectedIndex = comboBoxTeachers.SelectedIndex) != -1)
            {
                Teacher teacher = teachers.ElementAt(selectedIndex);
                loadTeacherPlan(teacher);
            }

            Cursor = Cursors.Default;
        }


        private void loadGroupPlan(Group g)
        { 
            int numberOfRows = classHours.Count;
            int numberOfColumns = days.Count;
            string[,] cells = new string[numberOfRows, numberOfColumns];
            int[,] subjectsIds = new int[numberOfRows, numberOfColumns];
            int[] subjects = new int[MAX_NUMBER_OF_SUBJECTS];
            int numberOfSubjects = 0;

            ScheduleDAO scheduleDAO = DAOFactory.getScheduleDAO(mode);
            IList<Schedule> list = scheduleDAO.getByGroup(g);
            //IList<Schedule> list = ScheduleManager.ScheduleManager.getWeeklySchedule();
            foreach (var elem in list)
            {
                //if (elem.Group.Equals(g))
                //{

                    int currentSubjectId = elem.Subject.Id;
                    int position = Array.IndexOf(subjects, currentSubjectId);
                    if (position < 0)
                    {
                        subjects[numberOfSubjects++] = currentSubjectId;
                    }

                    ClassHour classHour = elem.ClassHour;
                    int rowNumber = classHours.IndexOf(classHour);
                    DB.Domain.Core.Day day = elem.Day;
                    int columnNumber = days.IndexOf(day);

                    subjectsIds[rowNumber, columnNumber] = currentSubjectId;

                    string cell = elem.Subject.Name + "\n" + elem.Teacher.Name + "\n" + elem.Classroom.Name;
                    cells[rowNumber, columnNumber] = cell;
                //}

            }

            for (int r = 0; r < numberOfRows; r++)
            {
                string[] rowValues = new string[numberOfColumns];
                for (int c = 0; c < numberOfColumns; c++)
                {
                    if (cells[r, c] != null)
                    {
                        rowValues[c] = cells[r, c];
                    }
                    else
                    {
                        rowValues[c] = "\n\n";
                    }
                }
                grid.Rows[r].SetValues(rowValues);

                // na szybko
                int f = grid.ColumnCount;
                for (int b = 0; b < f; b++)
                {
                    grid.Rows[r].Cells[b].Style.BackColor = Color.White;
                }
                for (int b = 0; b < f; b++)
                {
                    if ((grid.Rows[r].Cells[b].Value.ToString()) != "\n\n")
                    {
                        int colorPosition = Array.IndexOf(subjects, subjectsIds[r, b]);
                        grid.Rows[r].Cells[b].Style.BackColor = colors[colorPosition];
                    }
                }
                //
                
            }

            autoResize();
            
        }


        private void loadCategoryPlan(Category category)
        {
            int numberOfRows = classHours.Count;
            int numberOfColumns = days.Count;
            string[,] cells = new string[numberOfRows, numberOfColumns];
            int[,] subjectsIds = new int[numberOfRows, numberOfColumns];
            int[] subjects = new int[MAX_NUMBER_OF_SUBJECTS];
            int numberOfSubjects = 0;

            ScheduleDAO scheduleDAO = DAOFactory.getScheduleDAO(mode);
            IList<Schedule> list = scheduleDAO.getAll();
            //IList<Schedule> list = ScheduleManager.ScheduleManager.getWeeklySchedule();
            foreach (var elem in list)
            {
                if (elem.Subject.Category.Id == category.Id)
                {

                    int currentSubjectId = elem.Subject.Id;
                    int position = Array.IndexOf(subjects, currentSubjectId);
                    if (position < 0)
                    {
                        subjects[numberOfSubjects++] = currentSubjectId;
                    }

                    ClassHour classHour = elem.ClassHour;
                    int rowNumber = classHours.IndexOf(classHour);
                    DB.Domain.Core.Day day = elem.Day;
                    int columnNumber = days.IndexOf(day);

                    subjectsIds[rowNumber, columnNumber] = currentSubjectId;

                    string cell = elem.Subject.Name + "\n" + elem.Teacher.Name;
                    cells[rowNumber, columnNumber] = cell;

                    int subjectTime = elem.Subject.Time;
                    if (subjectTime > 1)
                    {
                        for (int time = 1; time < subjectTime; time++)
                        {
                            cells[rowNumber + time, columnNumber] = cell;
                            subjectsIds[rowNumber + time, columnNumber] = currentSubjectId;
                        }
                    }

                }

            }

            for (int r = 0; r < numberOfRows; r++)
            {
                string[] rowValues = new string[numberOfColumns];
                for (int c = 0; c < numberOfColumns; c++)
                {
                    if (cells[r, c] != null)
                    {
                        rowValues[c] = cells[r, c];
                    }
                    else
                    {
                        rowValues[c] = "\n\n";
                    }
                }
                grid.Rows[r].SetValues(rowValues);

                // na szybko
                int f = grid.ColumnCount;
                for (int b = 0; b < f; b++)
                {
                    grid.Rows[r].Cells[b].Style.BackColor = Color.White;
                }
                for (int b = 0; b < f; b++)
                {
                    if ((grid.Rows[r].Cells[b].Value.ToString()) != "\n\n")
                    {
                        int colorPosition = Array.IndexOf(subjects, subjectsIds[r, b]);
                        grid.Rows[r].Cells[b].Style.BackColor = colors[colorPosition];
                    }
                }
                //

            }

            autoResize();

        }


        private void loadClassroomPlan(Classroom cr)
        { 
            int numberOfRows = classHours.Count;
            int numberOfColumns = days.Count;
            string[,] cells = new string[numberOfRows, numberOfColumns];

            ScheduleDAO scheduleDAO = DAOFactory.getScheduleDAO(mode);
            IList<Schedule> list = scheduleDAO.getByClassroom(cr);
            //IList<Schedule> list = ScheduleManager.ScheduleManager.getWeeklySchedule();
            foreach (var elem in list)
            {
                //if (elem.Classroom.Equals(cr))
                //{
                    ClassHour classHour = elem.ClassHour;
                    int rowNumber = classHours.IndexOf(classHour);
                    DB.Domain.Core.Day day = elem.Day;
                    int columnNumber = days.IndexOf(day);

                    string cell;
                    if (mode == Mode.School)
                    {
                        cell = elem.Subject.Name + "\n" + elem.Teacher.Name + "\n" + elem.Group.Name;
                    }
                    else
                    {
                        cell = elem.Subject.Name + "\n" + elem.Teacher.Name;
                    }
                    cells[rowNumber, columnNumber] = cell;

                    if (mode == Mode.University)
                    {
                        int subjectTime = elem.Subject.Time;
                        if (subjectTime > 1)
                        {
                            for (int time = 1; time < subjectTime; time++)
                            {
                                cells[rowNumber + time, columnNumber] = cell;
                            }
                        }
                    }
                //}

            }

            for (int r = 0; r < numberOfRows; r++)
            {
                string[] rowValues = new string[numberOfColumns];
                for (int c = 0; c < numberOfColumns; c++)
                {
                    if (cells[r, c] != null)
                    {
                        rowValues[c] = cells[r, c];
                    }
                    else
                    {
                        rowValues[c] = "\n\n";
                    }
                }
                grid.Rows[r].SetValues(rowValues);

                // na szybko
                int f = grid.ColumnCount;
                for (int b = 0; b < f; b++)
                {
                    grid.Rows[r].Cells[b].Style.BackColor = Color.White;
                }
                for (int b = 0; b < f; b++)
                {
                    if ((grid.Rows[r].Cells[b].Value.ToString()) != "\n\n")
                        grid.Rows[r].Cells[b].Style.BackColor = Color.LightBlue;
                }
                //

            }

            autoResize();
            
        }


        private void loadTeacherPlan(Teacher t)
        {
            int numberOfRows = classHours.Count;
            int numberOfColumns = days.Count;
            string[,] cells = new string[numberOfRows, numberOfColumns];

            ScheduleDAO scheduleDAO = DAOFactory.getScheduleDAO(mode);
            IList<Schedule> list = scheduleDAO.getByTeacher(t);
            //IList<Schedule> list = ScheduleManager.ScheduleManager.getWeeklySchedule();
            foreach (var elem in list)
            {
                //if (elem.Teacher.Equals(t)) {

                    ClassHour classHour = elem.ClassHour;
                    int rowNumber = classHours.IndexOf(classHour);
                    DB.Domain.Core.Day day = elem.Day;
                    int columnNumber = days.IndexOf(day);

                    string cell;
                    if (mode == Mode.School)
                    {
                        cell = elem.Subject.Name + "\n" + elem.Classroom.Name + "\n" + elem.Group.Name;
                    }
                    else
                    {
                        cell = elem.Subject.Name + "\n" + elem.Classroom.Name;
                    }
                    cells[rowNumber, columnNumber] = cell;

                    if (mode == Mode.University)
                    {
                        int subjectTime = elem.Subject.Time;
                        if (subjectTime > 1)
                        {
                            for (int time = 1; time < subjectTime; time++)
                            {
                                cells[rowNumber + time, columnNumber] = cell;
                            }
                        }
                    }

                    

                //}

            }

            // Sprawdzenie harmonogramu awaryjnego.
            //TimeSpan now = TimeSpan.FromTicks( DateTime.Now.Ticks );
            //MessageBox.Show(now.ToString());
            //EmergencyScheduleDAO emergencyScheduleDAO = DAOFactory.getEmergencyScheduleDAO(mode);
            //IList<EmergencySchedule> emergencyScheduleList = emergencyScheduleDAO.getByTeacher(t);
            //foreach(var emergencyScheduleElement in emergencyScheduleList)
            //{
                //emergencyScheduleElement.Date;
            //}
            
            // Wpisanie do grida.
            for (int r = 0; r < numberOfRows; r++)
            {
                string[] rowValues = new string[numberOfColumns];
                for (int c = 0; c < numberOfColumns; c++)
                {
                    if (cells[r, c] != null)
                    {
                        rowValues[c] = cells[r, c];
                    }
                    else
                    {
                        rowValues[c] = "\n\n";
                    }
                }
                grid.Rows[r].SetValues(rowValues);

                // na szybko
                int f = grid.ColumnCount;
                for (int b = 0; b < f; b++)
                {
                    grid.Rows[r].Cells[b].Style.BackColor = Color.White;
                }
                for (int b = 0; b < f; b++)
                {
                    if ((grid.Rows[r].Cells[b].Value.ToString()) != "\n\n")
                        grid.Rows[r].Cells[b].Style.BackColor = Color.LightBlue;
                }
                //

            }

            autoResize();

        }

        private void autoResize()
        {
            grid.AutoResizeColumns();
            grid.AutoResizeRows();
            ClientSize = new Size(countGridWidth(), countGridHeight() + 120);

        }

        private int countGridWidth()
        {
            int width = 0;
            foreach (DataGridViewColumn column in grid.Columns)
                if (column.Visible == true)
                    width += column.Width;
            width += grid.RowHeadersWidth;
            width += 50;
            return width;
        }

        private int countGridHeight()
        {
            int height = 0;
            foreach (DataGridViewRow row in grid.Rows)
                if (row.Visible == true)
                    height += row.Height;
            height += grid.ColumnHeadersHeight;
            height += 50;
            return height;
        }

    }
}
